from global_var import *
from All_Init import *
from Image import Element_Get
from PID import *
import global_var
from Test import *

class Cursor:
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y
Opt_Max_x = 0
Opt_Max_y = 0
Opt_Min_x = 240
Opt_Min_y = 170

hor_count = 0
ver_count = 0
Update = 0
cursor = Cursor()
Opt_margin = 10
hor_span = 100
ver_span = 20

def Opt_limit_clear():  
    global Opt_Max_x
    global Opt_Max_y
    global Opt_Min_x
    global Opt_Min_y
    Opt_Max_x = 0
    Opt_Max_y = 0
    Opt_Min_x = 240
    Opt_Min_y = 170
def update_counter(count, flag, limit):
    if flag == 1:
        count += 1
        lcd.clear(0x0000) 
    elif flag == -1:
        count -= 1
        lcd.clear(0x0000)

    if limit != 0:
        if count >= 0:
            count %= (limit + 1)
        if count < 0:
            count = limit - ((-count) % limit) + 1
    else:
        if count != 0:
            count = 0
    return count
def direct_count_horizontal(left_threshold, right_threshold):
    global hor_count
    limit_count_horizontal = (right_threshold - left_threshold) // hor_span
    hor_count = update_counter(hor_count, global_var.right_flag - global_var.left_flag, limit_count_horizontal)
def direct_count_vertical(up_threshold, down_threshold):
    global ver_count
    limit_count_vertical = (down_threshold - up_threshold) // ver_span
    ver_count = update_counter(ver_count, global_var.down_flag - global_var.up_flag, limit_count_vertical)
def _Opt_Ctrl_(up_threshold, down_threshold, left_threshold, right_threshold):
    global Update, cursor, last_cursor_x, last_cursor_y
    global Param_Change
    if global_var.Cursor_Show == 1:
        if(Param_Change == 0):
            direct_count_vertical(up_threshold, down_threshold)
            direct_count_horizontal(left_threshold, right_threshold)
            if hor_count != 0 or ver_count != 0 or Update == 1:
                if Update == 0:
                    Update = 1
                newX = left_threshold + hor_count * hor_span
                newY = up_threshold + ver_count * ver_span
                cursor.x = newX
                cursor.y = newY
                lcd.str16(cursor.x - Opt_margin, cursor.y, ">",0xffff)
            elif Update == 0:
                cursor.x = left_threshold
                cursor.y = up_threshold
                lcd.str16(cursor.x - Opt_margin, cursor.y, ">",0xffff)
        else:
            lcd.str16(cursor.x - Opt_margin, cursor.y, "*",0xffff)
Main_State = 1
Sub_State = 2
ItemFunc_State = 3
UI_State = Main_State
class Item:
    def __init__(self, Name, Row, Col, SubMenu, func, param=None):
        self.Name = Name
        self.Row = Row
        self.Col = Col
        self.func = func
        self.prior = None
        self.SubMenu = SubMenu
        self.param = param
    def Execute(self):
        if self.param is not None:
            self.func(self.param)
        else:
            self.func()

class Menu:
    global Current_Menu
    def __init__(self):
        self.next = None
        self.Prior = None
        self.Items = []
        self.current_item = None
    
    def AddItem(self, Item_Name, Item_Row, Item_Col, SubMenu, Item_Func, Param):
        self.Items.append(Item(Item_Name, Item_Row, Item_Col, SubMenu, Item_Func, Param))
    
    def Jump_Prior(self):
        global Current_Menu
        global UI_State
        global Save_flag
        if self.Prior is not None:
            """111"""
            if global_var.button1_flag == 1 and Param_Change == 0:
                lcd.clear(0x0000)
                Current_Menu = self.Prior
                UI_State = Sub_State
                Save_flag = 0
    
    def Jump_MenuAndFunc(self):
        global Current_Menu
        global UI_State
        global Param_Change
        self.current_item = None
        for i in self.Items:
            if i.SubMenu is not None:
                if global_var.right_flag == 1 and cursor.y == i.Row:
                    i.SubMenu.Prior = Current_Menu
                    Current_Menu = i.SubMenu
                    UI_State = Sub_State 
                    break
                
            elif i.func is not None and cursor.y == i.Row:
                if global_var.right_flag == 1:
                    i.prior = Current_Menu
                    self.current_item = i
                    UI_State = ItemFunc_State
                    break
    
    def Item_FuncExecute(self):
        global Current_Menu
        global UI_State
        global Save_flag
        self.current_item.Execute()
        if self.current_item.prior is not None:
            """111"""
            if global_var.button1_flag == 1 and Param_Change == 0:
                lcd.clear(0x0000)
                Current_Menu = self.current_item.prior
                UI_State = Sub_State
                Save_flag = 0


Scale = [0.001, 0.01, 0.1, 1, 10]
current_Scale = 1
select_idx=0

def Current_Scale_Select():
    global select_idx, current_Scale
    if global_var.up_flag == 1:
        select_idx = (select_idx-1 + 5) % 5
        current_Scale = Scale[select_idx]
    if global_var.down_flag == 1:
        select_idx = (select_idx+1 + 5) % 5
        current_Scale = Scale[select_idx]

Param_Change = 0

row_span = 20
col_span = 100
turnParam_show = 0
Save_flag = 0
cursor_normal = 0
value_change_flag = 0
Page_Num = 0
Current_Page = 0
Current_Page = 0

def Turn_Param_Task():
    global Current_Page, cursor, turnParam_show, Opt_Max_x, Opt_Max_y, Opt_Min_x, Opt_Min_y
    global Save_flag, cursor_normal, Param_Change, value_change_flag

    global_var.Cursor_Show = 1
    k = 0
    value_length = len(global_var.keys_list) if len(Param_dict) > len(global_var.keys_list) else len(Param_dict)
    Page_Num = value_length // 24  # 计算总页数

    lcd.str16(150, 20, f"Page:{Current_Page}/{Page_Num}", 0xffff)  # 显示当前页/总页数

    if Save_flag == 0:
        for i in range(12):
            for j in range(2):
                Opt_Max_x = j * col_span + 20 if (Opt_Max_x < j * col_span + 20) else Opt_Max_x
                Opt_Max_y = i * row_span + 50 if (Opt_Max_y < i * row_span + 50) else Opt_Max_y
                Opt_Min_x = j * col_span + 20 if (Opt_Min_x > j * col_span + 20) else Opt_Min_x
                Opt_Min_y = i * row_span + 50 if (Opt_Min_y > i * row_span + 50) else Opt_Min_y
        Save_flag = 1
    else:
        # 通用分页显示逻辑
        for i in range(12):
            for j in range(2):
                idx = k + Current_Page * 24
                if idx >= value_length:
                    break
                lcd.str16(
                    j * col_span + 20, 
                    i * row_span + 50,
                    global_var.keys_list[idx] + f":{global_var.Param_dict[global_var.keys_list[idx]]:.3f}", 
                    0xffff
                )
                k += 1
            if k >= value_length:
                break

    # 页码切换逻辑（保持不变）
    if Param_Change == 0 and Page_Num > 0:
        if cursor.x == Opt_Max_x and global_var.right_flag == 1:
            Current_Page = (Current_Page + 1) % (Page_Num + 1)
        elif cursor.x == Opt_Min_x and global_var.left_flag == 1:
            Current_Page = (Current_Page - 1) % (Page_Num + 1)

    # 其余逻辑保持不变...
    if (cursor.x == 20 and cursor.y == 50 and cursor_normal == 0):
        cursor_normal = 1

    if Save_flag == 1 and cursor_normal == 1:
        move_x = (cursor.x - 20) // hor_span
        move_y = (cursor.y - 50) // ver_span
        select_idx = move_y * 2 + move_x + Current_Page * 24

        if Param_Change == 0 and global_var.mid_flag == 1:
            Param_Change = 1 - Param_Change

        if Param_Change == 1:
            lcd.str16(20, 20, f"Scale:{current_Scale:.4f}", 0xffff)
            Current_Scale_Select()
            if global_var.right_flag == 1:
                global_var.Param_dict[global_var.keys_list[select_idx]] += current_Scale
                value_change_flag = 1
            elif global_var.left_flag == 1:
                global_var.Param_dict[global_var.keys_list[select_idx]] -= current_Scale
                value_change_flag = 1
            if global_var.mid_flag == 1 and value_change_flag == 1:
                Param_Change = 0
                value_change_flag = 0
                Write_Param_Update()

def CarStart(opt=0):
    if(opt==0):
        global_var.Normal_Go = 1
        global_var.Car_Go = 1
    else:
        global_var.Table_Go = 1
        global_var.Test_Go  =1

def _Execute_Task():
    global Opt_Max_x
    global Opt_Max_y
    global Opt_Min_x
    global Opt_Min_y
    
    global Cursor_Show
    if UI_State == Sub_State or UI_State == Main_State:
        global_var.Cursor_Show = 1
        Opt_limit_clear()
        for i in Current_Menu.Items:
            Opt_Max_x = i.Col if (Opt_Max_x < i.Col) else Opt_Max_x
            Opt_Max_y = i.Row if (Opt_Max_y < i.Row) else Opt_Max_y
            Opt_Min_x = i.Col if (Opt_Min_x > i.Col) else Opt_Min_x
            Opt_Min_y = i.Row if (Opt_Min_y > i.Row) else Opt_Min_y
            lcd.str16(i.Col, i.Row, i.Name,0xffff)
        Current_Menu.Jump_MenuAndFunc()
        Current_Menu.Jump_Prior()
    elif UI_State == ItemFunc_State:
        if (Save_flag == 0):
            Opt_limit_clear()
        Current_Menu.Item_FuncExecute()
    
def UI_Main():
    _Execute_Task()
    _Opt_Ctrl_(Opt_Min_y, Opt_Max_y, Opt_Min_x, Opt_Max_x) 

Main_Menu = Menu()
Car_Start_Menu = Menu()
PID_Menu = Menu()
Image_Menu = Menu()
Data_Menu = Menu()
Peri_Menu = Menu()

Current_Menu = Main_Menu

Main_Menu.AddItem("Start", 70, 40, Car_Start_Menu, None, None)
Main_Menu.AddItem("Param", 90, 40, PID_Menu, None, None)
Main_Menu.AddItem("Image", 110, 40, Image_Menu, None, None)
Main_Menu.AddItem("Data", 130, 40, Data_Menu, None, None)

Car_Start_Menu.AddItem("Normal_Start", 70, 40, None, CarStart, None)
Car_Start_Menu.AddItem("Table_Start", 90, 40, None, CarStart, 1)

PID_Menu.AddItem("Turn", 90, 40, None, Turn_Param_Task, None)

Image_Menu.AddItem("Boundary", 70, 40, None, Element_Get, 1)
Image_Menu.AddItem("Circle", 90, 40, None, Element_Get, 2)
Image_Menu.AddItem("Cross", 110, 40, None, Element_Get, 3)
Image_Menu.AddItem("Ramp", 130, 40, None, Element_Get, 4)
Image_Menu.AddItem("Zebra", 150, 40, None, Element_Get, 5)
Image_Menu.AddItem("CCD_data", 170, 40, None, Element_Get, 6)
Image_Menu.AddItem("Thres", 190, 40, None, Element_Get, 7)
Image_Menu.AddItem("Openart", 210, 40, None, Element_Get, 8)

Data_Menu.AddItem("PID", 70, 40, None, PID_Data, None)
Data_Menu.AddItem("Gyro", 90, 40, None, Gyro_Data, None)
